// 说话人识别服务类 - 基于Android代码逻辑实现
class SpeakerRecognitionService {
    constructor() {
        this.config = window.CONFIG || CONFIG;
        this.registeredSpeakers = new Map(); // 存储已注册的说话人信息
        this.groupId = "default_group4"; // 与Android代码保持一致
        this.sampleRate = 16000; // 16kHz采样率
        this.audioFormat = 0; // PCM格式
        this.threshold = 70.0; // 置信度阈值，与Android代码保持一致
        
        // 腾讯云API配置
        this.apiHost = "asr.tencentcloudapi.com";
        this.apiVersion = "2019-06-14";
        this.region = "ap-beijing";
        
        // 使用与Android代码相同的配置
        this.tencentAppId = "1329482420";
        this.tencentSecretId = "AKIDfFdqqdDakjU3PiuulRxJUVK1fBVgkeMt";
        this.tencentSecretKey = "PaovqZ5OUO5ZqvmRtHSQDoMvNejbGjz2";
        
        // 模拟模式（用于测试，避免CORS问题）
        this.mockMode = true; // 设置为true启用模拟模式
        this.mockSpeakerCounter = 0;
    }

    /**
     * 检查说话人（先验证，失败则注册）
     * @param {ArrayBuffer} audioData - 音频数据
     * @param {Object} speakerInfo - 说话人信息对象
     * @returns {Promise<Object>} 说话人识别结果
     */
    async checkSpeaker(audioData, speakerInfo) {
        try {
            console.log('checkSpeaker被调用，模拟模式状态:', this.mockMode);
            // 如果启用模拟模式，使用模拟数据
            if (this.mockMode) {
                console.log('使用模拟模式进行说话人识别');
                return this.mockSpeakerRecognition(audioData, speakerInfo);
            }
            
            if (this.registeredSpeakers.size > 0) {
                // 先尝试验证说话人
                const verifyResult = await this.verifySpeaker(audioData, speakerInfo);
                if (verifyResult.success) {
                    return verifyResult;
                }
            }
            
            // 验证失败或没有注册的说话人，进行注册
            return await this.enrollSpeaker(audioData, speakerInfo);
            
        } catch (error) {
            console.error('说话人检查失败:', error);
            return {
                success: false,
                error: error.message,
                speakerId: null,
                score: 0
            };
        }
    }

    /**
     * 说话人注册
     * @param {ArrayBuffer} audioData - 音频数据
     * @param {Object} speakerInfo - 说话人信息对象
     * @returns {Promise<Object>} 注册结果
     */
    async enrollSpeaker(audioData, speakerInfo) {
        try {
            const audioBase64 = this.arrayBufferToBase64(audioData);
            
            // 构建请求体 - 按照腾讯云API格式
            const requestBody = {
                Action: "VoicePrintEnroll",
                Version: this.apiVersion,
                Region: this.region,
                Request: {
                    VoiceFormat: this.audioFormat,
                    SampleRate: this.sampleRate,
                    Data: audioBase64,
                    SpeakerNick: `说话人${this.registeredSpeakers.size + 1}`,
                    GroupId: this.groupId
                }
            };

            console.log('说话人注册请求体:', requestBody);

            // 生成签名头
            const headers = await this.generateCloudApiHeaders("VoicePrintEnroll", JSON.stringify(requestBody));

            // 发送请求 - 腾讯云API需要特定的请求格式
            const response = await fetch(`https://${this.apiHost}/`, {
                method: 'POST',
                headers: {
                    ...headers,
                    'Content-Type': 'application/json; charset=utf-8'
                },
                body: JSON.stringify(requestBody)
            });

            if (!response.ok) {
                throw new Error(`HTTP错误: ${response.status}`);
            }

            const responseData = await response.json();
            console.log('说话人注册响应:', responseData);

            return this.handleSpeakerEnrollResponse(responseData, speakerInfo);

        } catch (error) {
            console.error('说话人注册失败:', error);
            
            // 如果是CORS错误，自动切换到模拟模式
            if (error.message.includes('Failed to fetch') || error.message.includes('CORS')) {
                console.log('检测到CORS错误，自动切换到模拟模式');
                this.mockMode = true;
                return this.mockSpeakerRecognition(audioData, speakerInfo);
            }
            
            return {
                success: false,
                error: error.message,
                speakerId: null,
                score: 0
            };
        }
    }

    /**
     * 说话人验证
     * @param {ArrayBuffer} audioData - 音频数据
     * @param {Object} speakerInfo - 说话人信息对象
     * @returns {Promise<Object>} 验证结果
     */
    async verifySpeaker(audioData, speakerInfo) {
        try {
            const audioBase64 = this.arrayBufferToBase64(audioData);
            
            // 构建请求体 - 按照腾讯云API格式
            const requestBody = {
                Action: "VoicePrintGroupVerify",
                Version: this.apiVersion,
                Region: this.region,
                Request: {
                    VoiceFormat: this.audioFormat,
                    SampleRate: this.sampleRate,
                    Data: audioBase64,
                    GroupId: this.groupId,
                    TopN: 1
                }
            };

            console.log('说话人验证请求体:', requestBody);

            // 生成签名头
            const headers = await this.generateCloudApiHeaders("VoicePrintGroupVerify", JSON.stringify(requestBody));

            // 发送请求
            const response = await fetch(`https://${this.apiHost}/`, {
                method: 'POST',
                headers: {
                    ...headers,
                    'Content-Type': 'application/json; charset=utf-8'
                },
                body: JSON.stringify(requestBody)
            });

            if (!response.ok) {
                throw new Error(`HTTP错误: ${response.status}`);
            }

            const responseData = await response.json();
            console.log('说话人验证响应:', responseData);

            return this.handleSpeakerVerifyResponse(responseData, audioData, speakerInfo);

        } catch (error) {
            console.error('说话人验证失败:', error);
            
            // 如果是CORS错误，自动切换到模拟模式
            if (error.message.includes('Failed to fetch') || error.message.includes('CORS')) {
                console.log('检测到CORS错误，自动切换到模拟模式');
                this.mockMode = true;
                return this.mockSpeakerRecognition(audioData, speakerInfo);
            }
            
            return {
                success: false,
                error: error.message,
                speakerId: null,
                score: 0
            };
        }
    }

    /**
     * 处理说话人注册响应
     * @param {Object} responseData - API响应数据
     * @param {Object} speakerInfo - 说话人信息对象
     * @returns {Object} 处理结果
     */
    handleSpeakerEnrollResponse(responseData, speakerInfo) {
        try {
            const response = responseData.Response;
            
            if (response.Error) {
                console.error('说话人注册错误:', response.Error.Code, response.Error.Message);
                return {
                    success: false,
                    error: `${response.Error.Code} - ${response.Error.Message}`,
                    speakerId: null,
                    score: 0
                };
            }

            const data = response.Data;
            const voicePrintId = data.VoicePrintId;
            const speakerId = `说话人${this.registeredSpeakers.size + 1}`;

            // 保存说话人信息
            this.registeredSpeakers.set(speakerId, voicePrintId);
            speakerInfo.speakerId = speakerId;

            console.log('说话人注册成功:', speakerId, voicePrintId);

            return {
                success: true,
                speakerId: speakerId,
                voicePrintId: voicePrintId,
                score: 100, // 注册成功，置信度设为100%
                isNewSpeaker: true
            };

        } catch (error) {
            console.error('解析说话人注册响应失败:', error);
            return {
                success: false,
                error: error.message,
                speakerId: null,
                score: 0
            };
        }
    }

    /**
     * 处理说话人验证响应
     * @param {Object} responseData - API响应数据
     * @param {ArrayBuffer} audioData - 原始音频数据
     * @param {Object} speakerInfo - 说话人信息对象
     * @returns {Object} 处理结果
     */
    handleSpeakerVerifyResponse(responseData, audioData, speakerInfo) {
        try {
            const response = responseData.Response;
            
            if (response.Error) {
                console.error('说话人验证错误:', response.Error.Code, response.Error.Message);
                return {
                    success: false,
                    error: `${response.Error.Code} - ${response.Error.Message}`,
                    speakerId: null,
                    score: 0
                };
            }

            const data = response.Data;
            const verifyTops = data.VerifyTops;

            if (!verifyTops || verifyTops.length === 0) {
                console.log('没有匹配到任何说话人，需要注册新说话人');
                return {
                    success: false,
                    error: '没有匹配到任何说话人',
                    speakerId: null,
                    score: 0
                };
            }

            const topResult = verifyTops[0];
            const speakerId = topResult.SpeakerId;
            const voicePrintId = topResult.VoicePrintId;
            const score = parseFloat(topResult.Score) || 0;

            if (score >= this.threshold) {
                console.log(`✅ 通过分数识别到已注册说话人: ${speakerId}, 置信度: ${score}%`);
                speakerInfo.speakerId = speakerId;
                
                return {
                    success: true,
                    speakerId: speakerId,
                    voicePrintId: voicePrintId,
                    score: score,
                    isNewSpeaker: false
                };
            } else {
                console.log(`❌ 说话人识别置信度较低: ${score}% < ${this.threshold}%，需要注册为新说话人`);
                return {
                    success: false,
                    error: `置信度不足: ${score}% < ${this.threshold}%`,
                    speakerId: null,
                    score: score
                };
            }

        } catch (error) {
            console.error('解析说话人验证响应失败:', error);
            return {
                success: false,
                error: error.message,
                speakerId: null,
                score: 0
            };
        }
    }

    /**
     * 生成腾讯云API签名头
     * @param {string} action - API动作
     * @param {string} requestBody - 请求体JSON字符串
     * @returns {Promise<Object>} 签名头
     */
    async generateCloudApiHeaders(action, requestBody) {
        const timestamp = Math.floor(Date.now() / 1000);
        const date = this.getDateString(timestamp);

        // 构建规范请求串
        const canonicalRequest = await this.buildCanonicalRequest(
            "POST", "/", "",
            `content-type:application/json; charset=utf-8\nhost:${this.apiHost}\n`,
            "content-type;host", requestBody
        );

        // 构建待签名字符串
        const stringToSign = await this.buildStringToSign(timestamp, date, canonicalRequest);

        // 计算签名
        const signature = await this.calculateSignature(this.tencentSecretKey, date, stringToSign);

        // 构建Authorization头
        const authorization = `TC3-HMAC-SHA256 Credential=${this.tencentSecretId}/${date}/asr/tc3_request, SignedHeaders=content-type;host, Signature=${signature}`;

        return {
            'Authorization': authorization,
            'Host': this.apiHost,
            'X-TC-Action': action,
            'X-TC-Timestamp': timestamp.toString(),
            'X-TC-Version': this.apiVersion,
            'X-TC-Region': this.region
        };
    }

    /**
     * 计算签名
     * @param {string} secretKey - 密钥
     * @param {string} date - 日期字符串
     * @param {string} stringToSign - 待签名字符串
     * @returns {Promise<string>} 签名
     */
    async calculateSignature(secretKey, date, stringToSign) {
        const secretDate = await this.hmacSHA256(`TC3${secretKey}`, date);
        const secretService = await this.hmacSHA256(secretDate, "asr");
        const secretSigning = await this.hmacSHA256(secretService, "tc3_request");
        return this.bytesToHex(await this.hmacSHA256(secretSigning, stringToSign));
    }

    /**
     * 构建待签名字符串
     * @param {number} timestamp - 时间戳
     * @param {string} date - 日期字符串
     * @param {string} canonicalRequest - 规范请求串
     * @returns {Promise<string>} 待签名字符串
     */
    async buildStringToSign(timestamp, date, canonicalRequest) {
        const credentialScope = `${date}/asr/tc3_request`;
        return `TC3-HMAC-SHA256\n${timestamp}\n${credentialScope}\n${await this.hashSHA256(canonicalRequest)}`;
    }

    /**
     * 构建规范请求串
     * @param {string} httpMethod - HTTP方法
     * @param {string} canonicalUri - 规范URI
     * @param {string} canonicalQueryString - 规范查询字符串
     * @param {string} canonicalHeaders - 规范头
     * @param {string} signedHeaders - 签名头
     * @param {string} requestPayload - 请求载荷
     * @returns {Promise<string>} 规范请求串
     */
    async buildCanonicalRequest(httpMethod, canonicalUri, canonicalQueryString, canonicalHeaders, signedHeaders, requestPayload) {
        return `${httpMethod}\n${canonicalUri}\n${canonicalQueryString}\n${canonicalHeaders}\n${signedHeaders}\n${await this.hashSHA256(requestPayload)}`;
    }

    /**
     * SHA256哈希
     * @param {string} text - 待哈希文本
     * @returns {string} 哈希值
     */
    async hashSHA256(text) {
        const encoder = new TextEncoder();
        const data = encoder.encode(text);
        const hashBuffer = await crypto.subtle.digest('SHA-256', data);
        return this.bytesToHex(new Uint8Array(hashBuffer));
    }

    /**
     * HMAC-SHA256
     * @param {string|Uint8Array} key - 密钥
     * @param {string} data - 数据
     * @returns {Uint8Array} HMAC结果
     */
    async hmacSHA256(key, data) {
        const encoder = new TextEncoder();
        const keyData = key instanceof Uint8Array ? key : encoder.encode(key);
        const dataToSign = encoder.encode(data);
        
        const cryptoKey = await crypto.subtle.importKey(
            'raw',
            keyData,
            { name: 'HMAC', hash: 'SHA-256' },
            false,
            ['sign']
        );
        
        const signature = await crypto.subtle.sign('HMAC', cryptoKey, dataToSign);
        return new Uint8Array(signature);
    }

    /**
     * 字节数组转十六进制字符串
     * @param {Uint8Array} bytes - 字节数组
     * @returns {string} 十六进制字符串
     */
    bytesToHex(bytes) {
        return Array.from(bytes)
            .map(b => b.toString(16).padStart(2, '0'))
            .join('');
    }

    /**
     * 获取日期字符串 (YYYY-MM-DD格式)
     * @param {number} timestamp - 时间戳
     * @returns {string} 日期字符串
     */
    getDateString(timestamp) {
        const date = new Date(timestamp * 1000);
        return date.toISOString().split('T')[0];
    }

    /**
     * ArrayBuffer转Base64
     * @param {ArrayBuffer} buffer - ArrayBuffer
     * @returns {string} Base64字符串
     */
    arrayBufferToBase64(buffer) {
        const bytes = new Uint8Array(buffer);
        let binary = '';
        for (let i = 0; i < bytes.byteLength; i++) {
            binary += String.fromCharCode(bytes[i]);
        }
        return btoa(binary);
    }

    /**
     * 获取已注册的说话人列表
     * @returns {Array} 说话人列表
     */
    getRegisteredSpeakers() {
        return Array.from(this.registeredSpeakers.keys());
    }

    /**
     * 清除所有已注册的说话人
     */
    clearRegisteredSpeakers() {
        this.registeredSpeakers.clear();
        console.log('已清除所有注册的说话人');
    }

    /**
     * 获取说话人数量
     * @returns {number} 说话人数量
     */
    getSpeakerCount() {
        return this.registeredSpeakers.size;
    }

    /**
     * 模拟说话人识别（用于测试，避免CORS问题）
     * @param {ArrayBuffer} audioData - 音频数据
     * @param {Object} speakerInfo - 说话人信息对象
     * @returns {Promise<Object>} 模拟识别结果
     */
    async mockSpeakerRecognition(audioData, speakerInfo) {
        // 模拟网络延迟
        await new Promise(resolve => setTimeout(resolve, 500 + Math.random() * 1000));
        
        console.log('使用模拟模式进行说话人识别，音频数据大小:', audioData.byteLength, 'bytes');
        
        // 模拟识别逻辑
        if (this.registeredSpeakers.size === 0) {
            // 没有已注册说话人，注册新说话人
            this.mockSpeakerCounter++;
            const speakerId = `说话人${this.mockSpeakerCounter}`;
            const voicePrintId = `mock_voiceprint_${this.mockSpeakerCounter}`;
            
            this.registeredSpeakers.set(speakerId, voicePrintId);
            speakerInfo.speakerId = speakerId;
            
            console.log('模拟注册新说话人:', speakerId);
            
            return {
                success: true,
                speakerId: speakerId,
                voicePrintId: voicePrintId,
                score: 100,
                isNewSpeaker: true
            };
        } else {
            // 有已注册说话人，模拟验证过程
            const speakers = Array.from(this.registeredSpeakers.keys());
            const randomSpeaker = speakers[Math.floor(Math.random() * speakers.length)];
            const score = 60 + Math.random() * 40; // 60-100分的随机分数
            
            if (score >= this.threshold) {
                // 验证成功
                speakerInfo.speakerId = randomSpeaker;
                console.log('模拟验证成功，说话人:', randomSpeaker, '置信度:', score.toFixed(1) + '%');
                
                return {
                    success: true,
                    speakerId: randomSpeaker,
                    voicePrintId: this.registeredSpeakers.get(randomSpeaker),
                    score: Math.round(score),
                    isNewSpeaker: false
                };
            } else {
                // 验证失败，注册新说话人
                this.mockSpeakerCounter++;
                const newSpeakerId = `说话人${this.mockSpeakerCounter}`;
                const newVoicePrintId = `mock_voiceprint_${this.mockSpeakerCounter}`;
                
                this.registeredSpeakers.set(newSpeakerId, newVoicePrintId);
                speakerInfo.speakerId = newSpeakerId;
                
                console.log('模拟验证失败，注册新说话人:', newSpeakerId, '原置信度:', score.toFixed(1) + '%');
                
                return {
                    success: true,
                    speakerId: newSpeakerId,
                    voicePrintId: newVoicePrintId,
                    score: 100,
                    isNewSpeaker: true
                };
            }
        }
    }

    /**
     * 设置模拟模式
     * @param {boolean} enabled - 是否启用模拟模式
     */
    setMockMode(enabled) {
        this.mockMode = enabled;
        console.log('说话人识别模拟模式:', enabled ? '已启用' : '已禁用');
    }
}

// 导出类
if (typeof module !== 'undefined' && module.exports) {
    module.exports = SpeakerRecognitionService;
} else {
    window.SpeakerRecognitionService = SpeakerRecognitionService;
}
